﻿using System;
using System.Collections.Concurrent;
using Grundy.Common;
using Grundy.Entity;
using System.Linq;
using Grundy.Message;

namespace Grundy.Licensing.Server
{
    public abstract class CountedConcurrentSessionsStrategy : LicensingStrategy
    {
        public CountedConcurrentSessionsStrategy(License license, LicenseEntitlementValidity licenseEntitlementValidity, FeatureIdentificationKey featureIdentificationKey) : base(license, licenseEntitlementValidity, featureIdentificationKey){ }
        
        protected override Guid CheckoutLicense(LicenseRequestInformation lri, object syncLock)
        {
            var clientIdentifiers = lri.ClientIdentifiers;
            var floatingLicense = (FloatingLicense)License;
            var clientType = floatingLicense.Client;
            
            var clientIdentifiersToUseEnumerable = clientIdentifiers.Where(i =>
                                         {
                                            var typeOfIdentifier = i.GetType();
                                            return clientType.GetIdentifiers().Contains(typeOfIdentifier);
                                         });
            var clientIdentifiersToUse = new IdentifierCollection(clientIdentifiersToUseEnumerable);

            lock (syncLock)
            {
                var matchingClientSession = clientSessions.Values.Where(i => i.IdentifiersUsedToIdentify.Equals(clientIdentifiersToUse)).FirstOrDefault();
                if (matchingClientSession != null)
                    return matchingClientSession.Id;

                return VerifyValidityAndCheckout(clientSessions, lri, clientIdentifiersToUse);
            }
        }

        protected abstract Guid VerifyValidityAndCheckout(ConcurrentDictionary<Guid, ClientSession> clientSessions, LicenseRequestInformation lri, IdentifierCollection clientIdentifiersToUse);
    }
}